#define GPCCON      (*(volatile unsigned long *)0x56000020)
#define GPDCON      (*(volatile unsigned long *)0x56000030)
#define GPGCON      (*(volatile unsigned long *)0x56000060)
#define LCDCON1     (*(volatile unsigned long *)0x4D000000)
#define LCDCON2     (*(volatile unsigned long *)0x4D000004)
#define LCDCON3     (*(volatile unsigned long *)0x4D000008)
#define LCDCON4     (*(volatile unsigned long *)0x4D00000C)
#define LCDCON5     (*(volatile unsigned long *)0x4D000010)
#define LCDSADDR1   (*(volatile unsigned long *)0x4D000014)
#define LCDSADDR2   (*(volatile unsigned long *)0x4D000018)
#define LCDSADDR3   (*(volatile unsigned long *)0x4D00001C)
#define TPAL        (*(volatile unsigned long *)0x4D000050)

#define U32		unsigned int 
#define U16		unsigned short 
#define U8		unsigned char 

#define PNRMODE		(3)			// 设置为TFT屏
#define BPPMODE		(0XC)			// 设置为16bpp模式
#define INVVDEN		(1)			//0=normal       1=inverted
#define HWSWP		(1)			//Half word swap control

//Timing parameter for 3.5' LCD
#define VBPD 		(12)			//垂直同步信号的后肩
#define VFPD 		(4)			//垂直同步信号的前肩
#define VSPW 		(5)			//垂直同步信号的脉宽

#define HBPD 		(22)			//水平同步信号的后肩
#define HFPD 		(33)			//水平同步信号的前肩
#define HSPW 		(44)			//水平同步信号的脉宽

#define CLKVAL 	    (6) 	

#define LINEVAL     (239)
#define HOZVAL      (319)

unsigned short LCDBUFFER[240][320];

void lcd_port_init()
{
	GPCCON = 0xAAAAAAAA;
	GPDCON = 0xAAAAAAAA;
}

void lcd_control_init()
{	
    LCDCON1 = (CLKVAL<<8)|(PNRMODE<<5)|(BPPMODE<<1)|(0<<0);
    LCDCON2 = (VBPD<<24)|(LINEVAL<<14)|(VFPD<<6)|(VSPW);
    LCDCON3 = (HBPD<<19)|(HOZVAL<<8)|(HFPD);
    LCDCON4 = (HSPW);
    LCDCON5 = (1<<11)|(INVVDEN<<9)|(INVVDEN<<8)|(HWSWP<<0);
    
    LCDSADDR1 = (((U32)LCDBUFFER>>22)<<21) | (((U32)LCDBUFFER>>1)&0x1fffff);
    LCDSADDR2 = (((U32)LCDBUFFER+240*320*2)>>1)&0x1fffff;
    LCDSADDR3 = (0<<11) | (320*2/2);
    
    TPAL = 0;
}

void lcd_init()
{
    lcd_port_init();
    lcd_control_init();
    
    //打开LCD电源
    GPGCON |= (0x3<<8);
    LCDCON5 |= (1<<3);   
    LCDCON1 |= 1;
}

void point(U16 x, U16 y, U32 color)
{
    unsigned int red, green, blue;
    
    red = (color>>19) & 0x1f;
    green = (color>>10) & 0x3f;
    blue = (color>>3) & 0x1f;
    LCDBUFFER[y][x] = (U16)((red<<11)|(green<<5)|blue);	
}

void Paint_Bmp(U16 x0, U16 y0, U16 wide, U16 high, const U8 *bmp)
{
    U16 x,y;
    U16 c;
    U32 p = 0;
    
    for( y = y0 ; y < y0+high ; y++ ) {
    	for( x = x0 ; x < x0+wide ; x++ ) {
    	    c = bmp[p] | (bmp[p+1]<<8) ;										
	    
	    if ( ( x < 320) && ( y < 240) )
	        LCDBUFFER[y][x] = c ;
		
	    p = p + 2 ;	
    	}
    }
}

void clearSrc(unsigned int color)
{
    TPAL = (1<<24)|(color&0xffffff);	
}

extern unsigned char qq_bmp[90200];

void lcd_test()
{
    int x;
    
    for(x=0; x<320; x++) {
        point(x++,150,0x0000FF);
    }

    Paint_Bmp(0,0,220,220,qq_bmp);
    
    //clearSrc(0xff0000);
}
